<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // ------------------------------------------------------------
    // 构造函数 constructor：类似于现实中的模具，图纸，模版
    // function Cat(name, color) {
    //     this.name = name
    //     this.color = color
    // }
    // var cat1 = new Cat('太子', '黑色');
    // console.log(cat1.name);//太子
    // console.log(cat1.color);//黑色


    // function Person() { }
    // // 实例对象继承了原型的constructor属性，指向自己的构造函数
    // var p = new Person();
    // // 构造函数原型对象上的constructor属性指向的也是构造函数，p.constructor 和Person.prototype.constructor，指向的是同一个对象
    // console.log(p.constructor === Person);//true
    // console.log(Person === Person.prototype.constructor);//true
    // console.log(p.constructor === Person.prototype.constructor);//true
    // console.log(p.__proto__ === Person.prototype);//true

    // ----------------------------------------------------------
    // prototype 原型：类似于女娲捏人
    // 只有函数才拥有prototype属性，对象没有
    // function Animal(name) {
    //     this.name = name;
    //     // 如果把方法挂载在实例身上，每次实例化的时候都会开辟新的内存空间
    //     this.eat = function () {
    //         console.log('我喜欢吃肉');
    //     }

    // }
    // // 推荐构造函数中声明属性，构造函数的原型上挂载方法
    // Animal.prototype.run = function () {
    //     console.log('我跑得很快');

    // }
    // var dog = new Animal('狗');
    // var tiger = new Animal('老虎');

    // tiger.eat()
    // dog.eat()
    // console.log(dog.eat === tiger.eat);//false

    // tiger.run()
    // dog.run()
    // console.log(dog.run === tiger.run);//true

    // 对象
    // var obj = {
    //     age: 18
    // }
    // // obj.prototype.name = '小丽';//报错
    // obj.name = '小丽';
    // console.log(obj);

    // ------------------------------------------------------------
    // __proto__
    // function Pin() { }
    // var p = new Pin();
    // // Pin.prototype和p.constructor.prototype和p.__proto__指向构造函数Pin的原型对象
    // // p.constructor指向构造函数Pin
    // console.log(Pin.prototype === p.constructor.prototype);//true
    // console.log(p.__proto__ === Pin.prototype);//true
    // console.log(p.__proto__ === p.constructor.prototype);//true

    // ---------------------------------------------------------------

    // 原型链
    //注意：在js中所有的函数（构造函数）都属于Function的实例
    // function Person(name) {
    //     this.name = name

    // }
    // Person.prototype.name = 'Jay'
    // var p = new Person('Join')
    // console.log(p.name);//Join
    // // Jay
    // console.log(p.__proto__.name);// console.log(p.constructor.prototype.name);


    // // 对象字面量的原型链
    // // var a = {};
    // console.log(a.__proto__.__proto__);//null


    // 内置对象构造函数的原型链
    // var obj = new Object();
    // console.log(obj.__proto__ === Object.prototype);//true
    // console.log(obj.__proto__.constructor === Object);//true
    // console.log(Object.prototype.constructor === Object);//true


    // // 自定义对象
    // function Person() { }
    // // 函数构造函数的原型链
    // var fn = new Function();
    // // 自己的隐式原型指向自己原型对象
    // console.log(Function.__proto__ === Function.prototype);//true
    // // 自己是自己的实例，也可以作为构造函数使用
    // console.log(fn.prototype.constructor === fn);//true
    // // Function的原型对象指向Object的原型对象
    // console.log(Function.prototype.__proto__ === Object.prototype);//true
    // //所有构造函数都是Function的一个实例
    // console.log(Function.prototype === Object.__proto__);//true
    // console.log(Function.prototype === Person.__proto__);//true













</script>

</html>